package cn.turboinfo.fuyang.api.domain.share.usecase.order;

import cn.turboinfo.fuyang.api.domain.common.service.category.CategoryService;
import cn.turboinfo.fuyang.api.domain.common.service.division.DivisionService;
import cn.turboinfo.fuyang.api.domain.common.service.order.ServiceOrderService;
import cn.turboinfo.fuyang.api.domain.common.service.product.ProductService;
import cn.turboinfo.fuyang.api.domain.common.service.shop.HousekeepingShopService;
import cn.turboinfo.fuyang.api.domain.common.service.staff.HousekeepingStaffService;
import cn.turboinfo.fuyang.api.domain.common.usecase.AbstractUseCase;
import cn.turboinfo.fuyang.api.domain.util.BeanHelper;
import cn.turboinfo.fuyang.api.domain.util.PhoneUtils;
import cn.turboinfo.fuyang.api.entity.common.pojo.category.Category;
import cn.turboinfo.fuyang.api.entity.common.pojo.division.Division;
import cn.turboinfo.fuyang.api.entity.common.pojo.order.ServiceOrder;
import cn.turboinfo.fuyang.api.entity.common.pojo.product.Product;
import cn.turboinfo.fuyang.api.entity.common.pojo.shop.HousekeepingShop;
import cn.turboinfo.fuyang.api.entity.common.pojo.spec.Spec;
import cn.turboinfo.fuyang.api.entity.common.pojo.staff.HousekeepingStaff;
import cn.turboinfo.fuyang.api.entity.share.fo.order.ShareServiceOrderFO;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.api.request.QPage;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.response.QResponse;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 订单列表
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class ShareListServiceOrderUseCase extends AbstractUseCase<ShareListServiceOrderUseCase.InputData, ShareListServiceOrderUseCase.OutputData> {

    private final ServiceOrderService serviceOrderService;

    private final DivisionService divisionService;

    private final ProductService productService;

    private final HousekeepingShopService housekeepingShopService;

    private final HousekeepingStaffService housekeepingStaffService;

    private final CategoryService categoryService;

    @Override
    protected OutputData doAction(InputData inputData) {

        QResponse<ServiceOrder> response = serviceOrderService.findAll(inputData.request, inputData.getRequestPage());

        List<ServiceOrder> serviceOrderList = new ArrayList<>(response.getPagedData());

        // 查询地区
        Set<Long> provinceCodeSet = serviceOrderList.stream()
                .map(ServiceOrder::getDivisionId)
                .collect(Collectors.toSet());

        Map<Long, Division> divisionMap = divisionService.findByIdCollection(provinceCodeSet)
                .stream()
                .collect(Collectors.toMap(Division::getId, o -> o));

        // 查询产品
        Set<Long> productIdSet = serviceOrderList.stream()
                .map(ServiceOrder::getProductId)
                .collect(Collectors.toSet());

        Map<Long, Product> productMap = productService.findByIdCollection(productIdSet)
                .stream()
                .collect(Collectors.toMap(Product::getId, o -> o));

        // 查询门店
        Set<Long> shopIdSet = serviceOrderList.stream()
                .map(ServiceOrder::getShopId)
                .collect(Collectors.toSet());

        Map<Long, HousekeepingShop> shopMap = housekeepingShopService.findByIdCollection(shopIdSet)
                .stream()
                .collect(Collectors.toMap(HousekeepingShop::getId, o -> o));

        // 查询家政员
        Set<Long> staffIdSet = serviceOrderList.stream()
                .map(ServiceOrder::getStaffId)
                .collect(Collectors.toSet());

        Map<Long, HousekeepingStaff> staffMap = housekeepingStaffService.findByIdCollection(staffIdSet)
                .stream()
                .collect(Collectors.toMap(HousekeepingStaff::getId, o -> o));

        // 查询分类
        Set<Long> categoryIdSet = serviceOrderList.stream()
                .map(ServiceOrder::getCategoryId)
                .collect(Collectors.toSet());

        Map<Long, Category> categoryMap = categoryService.findByIdCollection(categoryIdSet)
                .stream()
                .collect(Collectors.toMap(Category::getId, o -> o));

        List<ShareServiceOrderFO> foList = serviceOrderList.stream()
                .map(it -> {
                    ShareServiceOrderFO.ShareServiceOrderFOBuilder builder = ShareServiceOrderFO.builder();
                    BeanHelper.copyPropertiesToBuilder(builder, ShareServiceOrderFO.class, it);

                    Long divisionId = it.getDivisionId();
                    if (divisionId != null && divisionMap.containsKey(divisionId)) {
                        builder.divisionName(divisionMap.get(divisionId).getAreaName());
                    }

                    if (it.getProductId() != null && productMap.containsKey(it.getProductId())) {
                        builder.productName(productMap.get(it.getProductId()).getName());
                    }

                    if (it.getShopId() != null && shopMap.containsKey(it.getShopId())) {
                        builder.shopName(shopMap.get(it.getShopId()).getName());
                    }

                    if (it.getStaffId() != null && staffMap.containsKey(it.getStaffId())) {
                        HousekeepingStaff staff = staffMap.get(it.getStaffId());
                        builder.staffCode(staff.getCode())
                                .staffName(staff.getName());
                    }

                    if (it.getCategoryId() != null && categoryMap.containsKey(it.getCategoryId())) {
                        builder.categoryName(categoryMap.get(it.getCategoryId()).getName());
                    }

                    if (it.getSpecList() != null && it.getSpecList().size() > 0) {
                        builder.specNameList(it.getSpecList()
                                .stream()
                                .map(spec -> String.join("-", makeSpecName(spec)))
                                .toList()
                        );
                    }

                    return builder
                            .contactMobile(PhoneUtils.maskPhoneNum(it.getMobile()))
                            .contactGender(it.getGenderType())
                            .build();
                })
                .toList();

        QResponse<ShareServiceOrderFO> foResponse = new QResponse<>(response.getPage(), response.getPageSize(), foList, response.getTotal());

        return OutputData.builder()
                .qResponse(foResponse)
                .build();
    }

    private List<String> makeSpecName(Spec spec) {
        List<String> nameList = new ArrayList<>();

        nameList.add(spec.getName());

        if (spec.getChildren() != null && spec.getChildren().size() > 0) {
            for (Spec item : spec.getChildren()) {
                nameList.addAll(makeSpecName(item));
            }
        }

        return nameList;
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InputData extends AbstractUseCase.InputData {

        private QRequest request;

        private QPage requestPage;

    }

    @Getter
    @Setter
    @Builder
    public static class OutputData extends AbstractUseCase.OutputData {

        private QResponse<ShareServiceOrderFO> qResponse;

    }
}
